package com.project.service.impl;

import com.project.common.exception.BusinessException;
import com.project.model.User;
import com.project.service.AuthService;
import com.project.service.UserService;
import com.project.utils.JwtUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class AuthServiceImpl implements AuthService {

    private final AuthenticationManager authenticationManager;
    private final JwtUtils jwtUtils;
    private final UserService userService;

    // 使用内存缓存存储已注销的token
    private static final Map<String, String> TOKEN_BLACKLIST = new ConcurrentHashMap<>();

    @Override
    public String login(String username, String password) {
        try {
            // 尝试认证
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
            );
            
            // 获取用户信息
            User user = userService.getUserByUsername(username);
            if (user == null) {
                throw new BusinessException("用户不存在");
            }
            
            // 检查用户状态
            if (user.getStatus() != 1) {
                throw new BusinessException("用户已被禁用");
            }
            
            // 生成token
            return jwtUtils.generateToken(username, user.getId());
        } catch (BadCredentialsException e) {
            throw new BusinessException(401, "用户名或密码错误");
        } catch (Exception e) {
            throw new BusinessException("登录失败：" + e.getMessage());
        }
    }

    @Override
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return userService.getUserByUsername(authentication.getName());
    }

    @Override
    @Transactional
    public void logout(String token) {
        try {
            // 验证 token
            if (!jwtUtils.validateToken(token)) {
                return;
            }

            // 将 token 加入黑名单
            String username = jwtUtils.getUsernameFromToken(token);
            TOKEN_BLACKLIST.put(token, username);

            // 启动一个定时任务，在token过期后从黑名单中移除
            long remainingTime = jwtUtils.getRemainingTime(token);
            if (remainingTime > 0) {
                ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
                scheduler.schedule(() -> TOKEN_BLACKLIST.remove(token), remainingTime, TimeUnit.MILLISECONDS);
                scheduler.shutdown();
            }
        } catch (Exception e) {
            log.error("退出登录失败", e);
            throw new BusinessException("退出登录失败");
        }
    }

    // 添加检查token是否在黑名单中的方法
    public boolean isTokenBlacklisted(String token) {
        return TOKEN_BLACKLIST.containsKey(token);
    }
} 